export class BlueUtils {
  constructor() {
    this.deviceId = '54:6C:0E:35:78:18'
    this.searchIng = false
    this.serviceTimer = null
    this.serviceScanTime = 0//如果扫描次数超过3次重新扫描
    this.blueToothReady = null//准备就绪回调
    this.blueToothBack = null//蓝牙返回数据回调
    this.blueToothError = null//蓝牙初始化错误
    this.REQUEST_OPEN_BT_CODE = 1000
    this.init()
  }

  showToast(msg) {
    uni.showToast({title: msg})
  }

  promiseBackSuccess(fn, e, back = null) {
    console.log(fn + "---success", e)
    if (back) back(e)
  }

  promiseBackFail(fn, e, back = null) {
    console.log(fn + "---fail", e)
    if (back) back(e)
  }

  promiseBackWarning(fn, state, e, back = null) {
    console.error(fn + "---" + state, e)
    if (back) back(e)
  }

  async init() {
    let _bluetooth_adapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
    this.main_activity = plus.android.runtimeMainActivity();//Android界面
    this.blue_client = _bluetooth_adapter.getDefaultAdapter();//蓝牙Adapter
    await this.canBlueToothUse()
  }

  async canBlueToothUse() {//蓝牙硬件是否可用
    console.log("canBlueToothUse1", this.blueToothError)
    if (!this.blue_client) this.blueToothError = "当前设备不支持蓝牙！"
    //申请定位权限 todo 还需要判断定位功能是否开启
    if (!this.blueToothError || this.blueToothError === "定位权限被拒绝！")
      this.blueToothError = await this.openLocationPermission()
    //获取蓝牙状态
    if (!this.blueToothError || this.blueToothError === "蓝牙未打开！")
      this.blueToothError = await this.turnOnBluetoothPromise()
    console.log("canBlueToothUse2", this.blueToothError)
    if (this.blueToothError) this.showToast(this.blueToothError)
    return this.blueToothError ? false : true
  }

  openLocationPermission() {// 申请定位权限
    return new Promise((resolve, reject) => {
      plus.android.requestPermissions(['android.permission.ACCESS_FINE_LOCATION'],
          e => {
            if (e.deniedAlways.length > 0) this.promiseBackFail("requestPermissions_ACCESS_FINE_LOCATION", "定位权限被拒绝！", reject)
            if (e.deniedPresent.length > 0) this.promiseBackFail("requestPermissions_ACCESS_FINE_LOCATION", "定位权限被拒绝！", reject)
            if (e.granted.length > 0) this.promiseBackSuccess("requestPermissions_ACCESS_FINE_LOCATION", "", resolve)
          },
          err => {
            this.showToast("申请权限出错！")
            this.promiseBackFail("requestPermissions_ACCESS_FINE_LOCATION", JSON.stringify(err), reject)
          });
    })
  }

  turnOnBluetoothPromise() {
    return new Promise((resolve, reject) => {
      this.turnOnBluetooth({
        backFn: openRes => {
          resolve(openRes ? "" : "蓝牙未打开！")
        }
      })
    })
  }

  turnOnBluetooth({backFn}) {
    //这里使用promise不管用
    if (this.blue_client != null && !this.blue_client.isEnabled()) {
      let _intent = plus.android.importClass('android.content.Intent')
      let intent = new _intent(this.blue_client.ACTION_REQUEST_ENABLE)
      this.main_activity.onActivityResult = (requestCode, resultCode, data) => {
        console.log("turnOnBluetooth==onActivityResult", requestCode, resultCode)
        if (requestCode == this.REQUEST_OPEN_BT_CODE) {
          let openRes = resultCode == -1;
          if (backFn) backFn(openRes)
        }
      };
      this.main_activity.startActivityForResult(intent, this.REQUEST_OPEN_BT_CODE)
    }
    //如果已经打开返回true
    if (this.blue_client != null && this.blue_client.isEnabled()) {
      console.log("turnOnBluetooth==蓝牙已经打开")
      backFn(true)
    }
  }

  turnOffBluetooth() {//关闭蓝牙
    if (this.blue_client != null && this.blue_client.isEnabled()) this.blue_client.disable()
  }

  /**
   * 开启蓝牙扫描
   */
  async startBluetoothDevicesDiscovery({readyBack = null, valueBack = null}) {
    let blueToothUse = await this.canBlueToothUse()
    if (!blueToothUse) return
    if (readyBack) this.blueToothReady = readyBack
    if (valueBack) this.blueToothBack = valueBack
    if (this.searchIng) await this.stopBluetoothDiscovery()
    console.log("//////////////startBluetoothDevicesDiscovery//////////////")
    this.listenBlueToothAdapter()
    let openRes = await this.openBlueTooth()
    let startDisRes = await this.startDiscovery()
    this.searchIng = true
  }

  async stopBluetoothDiscovery() {
    console.log("stopBluetoothDiscovery")
    this.clearServiceTimer()
    await this.stopDiscovery()
    await this.closeBlueTooth()
    this.searchIng = false
  }

  openBlueTooth() {
    return new Promise((resolve, reject) => {
      plus.bluetooth.openBluetoothAdapter({
        success: e => this.promiseBackSuccess("openBluetoothAdapter", e, resolve),
        fail: e => this.promiseBackFail("openBluetoothAdapter", e, reject)
      })
    })
  }

  closeBlueTooth() {
    return new Promise((resolve, reject) => {
      plus.bluetooth.closeBluetoothAdapter({
        success: e => this.promiseBackSuccess("closeBluetoothAdapter", e, resolve),
        fail: e => this.promiseBackFail("closeBluetoothAdapter", e, reject)
      })
    })
  }

  startDiscovery() {
    return new Promise((resolve, reject) => {
      plus.bluetooth.startBluetoothDevicesDiscovery({
        // services: [this.deviceId],
        allowDuplicatesKey: false,
        success: e => this.promiseBackSuccess("startBluetoothDevicesDiscovery", e, resolve),
        fail: e => this.promiseBackFail("startBluetoothDevicesDiscovery", e, reject)
      });
    })
  }

  stopDiscovery() {
    return new Promise((resolve, reject) => {
      plus.bluetooth.stopBluetoothDevicesDiscovery({
        success: e => this.promiseBackSuccess("stopBluetoothDevicesDiscovery", e, resolve),
        fail: e => this.promiseBackFail("stopBluetoothDevicesDiscovery", e, reject)
      });
    })
  }

  listenBlueToothAdapter() {
    plus.bluetooth.onBluetoothAdapterStateChange(e => {
      console.log('onBluetoothAdapterStateChange: ' + JSON.stringify(e));
    });
    plus.bluetooth.onBluetoothDeviceFound(e => {
      console.log("onBluetoothDeviceFound===")
      let devices = e.devices;
      for (let i in devices) {
        let deviceObj = devices[i]
        if (deviceObj.deviceId == this.deviceId) {
          console.error("onBluetoothDeviceFound deviceId: ", deviceObj.deviceId)
          this.connectDevice()
        } else {
          console.log("onBluetoothDeviceFound deviceId: ", deviceObj.deviceId)
        }
      }
    });
  }

  async connectDevice() {
    this.showToast("扫描到目标蓝牙！")
    await this.stopDiscovery()
    plus.bluetooth.createBLEConnection({
      deviceId: this.deviceId,
      success: e => {
        this.promiseBackSuccess("createBLEConnection", e)
        this.getServices()
      },
      fail: e => this.promiseBackFail("createBLEConnection", e),
    })
  }

  getServices() {
    this.serviceTimer = setInterval(() => {
      plus.bluetooth.getBLEDeviceServices({
        deviceId: this.deviceId,
        success: e => {
          let services = e.services;
          console.log('getBLEDeviceServices success: ' + services.length);
          for (let i in services) {
            console.log("getBLEDeviceServices" + i + ': ' + JSON.stringify(services[i]));
          }
          if (services.length > 0) {
            console.log("getServices---service存在！！！！")
            this.listenValueChange()
            this.clearServiceTimer()
          } else {
            this.serviceScanTime += 1
          }
          //如果连续4次都是service不存在就重新连接蓝牙
          if (this.serviceScanTime > 4) this.startBluetoothDevicesDiscovery({})
        },
        fail: async e => {
          this.promiseBackFail("getBLEDeviceServices", e)
          this.clearServiceTimer()
          await this.startBluetoothDevicesDiscovery({})
        }
      });
    }, 1000)
  }

  clearServiceTimer() {
    console.log("clearServiceTimer---")
    this.serviceScanTime = 0
    if (this.serviceTimer) {
      clearInterval(this.serviceTimer)
      this.serviceTimer = null
    }
  }

  listenValueChange() {
    plus.bluetooth.notifyBLECharacteristicValueChange({
      deviceId: this.deviceId,
      serviceId: '6E400001-B5A3-F393-E0A9-E50E24DCCA9E',
      characteristicId: '6E400003-B5A3-F393-E0A9-E50E24DCCA9E',
      success: e => {
        this.showToast("蓝牙连接成功！")
        this.promiseBackSuccess("notifyBLECharacteristicValueChange", e)
        if (this.blueToothReady) this.blueToothReady()
      },
      fail: async e => {
        this.promiseBackFail("notifyBLECharacteristicValueChange", e)
        await this.startBluetoothDevicesDiscovery({})
      },
    })
    this.readValueListener()
  }

  /**
   * 监听数据返回
   */
  readValueListener() {
    plus.bluetooth.onBLECharacteristicValueChange(e => {
      console.error("2>>>onBLECharacteristicValueChange >>>>>", JSON.stringify(e))
      // console.error("2.1>>>onBLECharacteristicValueChange >>>>>", e.value)
      if (this.blueToothBack) this.blueToothBack(e)
    })
  }

  /**
   * 写入数据
   */
  writeValue(value) {
    return new Promise((resolve, reject) => {
      plus.bluetooth.writeBLECharacteristicValue({
        deviceId: this.deviceId,
        serviceId: "6E400001-B5A3-F393-E0A9-E50E24DCCA9E",
        characteristicId: "6E400002-B5A3-F393-E0A9-E50E24DCCA9E",
        value: value,
        success: e => this.promiseBackWarning("1>>>writeBLECharacteristicValue", "success", e, resolve),
        fail: e => this.promiseBackWarning("writeBLECharacteristicValue", "fail", e, reject)
      })
    })
  }
}
